<template>
  <div class="page-container">
    <div class="header">
      <h1 class="title">人脸识别系统</h1>
      <p class="subtitle">使用摄像头进行人脸检测和分析</p>
    </div>
  
  
    <el-card class="camera-container">
    <div class="camera-section">
      <div class="preview-wrapper">
        <div class="preview-label">实时预览</div>
        <video ref="video" class="camera-preview" v-show="isCameraActive"></video>
        <img v-if="photoData" :src="photoData" class="photo-preview">
        <div v-else-if="!isCameraActive" class="placeholder">
          <el-icon :size="50"><Camera /></el-icon>
          <p>请点击"打开摄像头"开始</p>
        </div>
      </div>
      
      <div class="button-group">
        <el-tooltip content="打开摄像头" placement="top">
          <el-button type="primary" @click="openCamera" :disabled="isCameraActive" circle>
            <el-icon><VideoCamera /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="关闭摄像头" placement="top">
          <el-button type="danger" @click="stopCamera" :disabled="!isCameraActive" circle>
            <el-icon><SwitchButton /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="拍照" placement="top">
          <el-button type="success" @click="takePhoto" :disabled="!isCameraActive" circle>
            <el-icon><Camera /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="重新拍照" placement="top">
          <el-button type="warning" @click="retakePhoto" :disabled="!photoData" circle>
            <el-icon><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
        
        <el-tooltip content="上传照片" placement="top">
          <el-button type="info" @click="uploadPhoto" :disabled="!photoData" :loading="isUploading" circle>
            <el-icon><Upload /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
      
      <div class="status-indicator" :class="{ active: isCameraActive }">
        <span class="indicator-dot"></span>
        {{ isCameraActive ? '摄像头已开启' : '摄像头已关闭' }}
      </div>
    </div>
    
    <div class="result-section" v-if="faceResult">
      <el-divider>
        <el-icon><DataAnalysis /></el-icon> 人脸识别结果
      </el-divider>
      
      
      
      <el-table :data="[faceResult]" border style="width: 100%" stripe>
  <el-table-column prop="image" label="图片结果" width="180">
    <template #default="scope">
      <img :src="scope.row.image" class="result-image">
    </template>
  </el-table-column>
  <el-table-column prop="face_probability" label="置信度" align="center">
    <template #default="scope">
      <el-progress
        :percentage="parseFloat(scope.row.face_probability) * 100"
        :format="formatConfidence"
        :stroke-width="15"
        :color="confidenceColor(parseFloat(scope.row.face_probability))"
      />
    </template>
  </el-table-column>

  <el-table-column prop="face_num" label="人脸数量" align="center"></el-table-column>
 
  <el-table-column prop="blur" label="模糊度" align="center">
    <template #default="scope">
      <span>{{ scope.row.blur }}</span>
    </template>
  </el-table-column>
  <el-table-column prop="illumination" label="光照" align="center"></el-table-column>
  <el-table-column prop="eye_status" label="眼睛状态" align="center"></el-table-column>
  <el-table-column prop="accessories" label="配饰" align="center"></el-table-column>
  <el-table-column prop="face_type" label="人脸类型" align="center"></el-table-column>
  <el-table-column prop="occlusion" label="遮挡" align="center"></el-table-column>
  <el-table-column prop="angle" label="角度" align="center"></el-table-column>
  <el-table-column prop="location" label="位置" align="center"></el-table-column>
  <el-table-column prop="face_token" label="Face Token" width="180"></el-table-column>
</el-table>
    </div>
  </el-card>
  <div class="bottom-right-button">
          <el-button @click="goBackToFileSystem">返回主页面</el-button>
        </div>
  <div class="footer">
      <p> 人脸识别功能 - 参赛作品</p>
    </div>
  </div>
</template>

<script setup>
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { ref } from 'vue';
import {
  VideoCamera,
  SwitchButton,
  Camera,
  Refresh,
  Upload,
  DataAnalysis
} from '@element-plus/icons-vue';

const video = ref(null);
const stream = ref(null);
const isCameraActive = ref(false);
const photoData = ref(null);
const isUploading = ref(false);
const faceResult = ref(null);

const formatConfidence = (percentage) => {
  return percentage.toFixed(2) + '%';
};

const confidenceColor = (confidence) => {
  const score = confidence * 100;
  if (score > 80) return '#67C23A';
  if (score > 60) return '#E6A23C';
  return '#F56C6C';
};
function dataURLtoBlob(dataurl) {
  const arr = dataurl.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}
const goBackToFileSystem = () => {
    window.location.href = '/filesystem';
  };


const uploadPhoto = async () => {
  try{
  if (!photoData.value) return;
  
  isUploading.value = true;
  
    const formData = new FormData();
     // 检查是否是base64
     if (typeof photoData.value === 'string' && photoData.value.startsWith('data:')) {
      const blob = dataURLtoBlob(photoData.value);
      formData.append('file', blob, 'photo.jpg');
    } else {
      formData.append('file', photoData.value);
    }
    
    const response = await axios.post('http://localhost:8083/user/FaceToken', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    if(!(response.data.success)){
    ElMessage.error('上传失败:原因:'+response.data.errorMsg );
 
    isUploading.value = false;
  }else{

    faceResult.value = {
      image: photoData.value,
      face_token: response.data.data.face_token,
      face_num: response.data.data.face_num,
      confidence: response.data.data.face_probability,
      blur: response.data.data.blur,
      illumination: response.data.data.illumination,
      eye_status: response.data.data.eye_status,
      accessories: response.data.data.accessories,
      face_type: response.data.data.face_type,
      occlusion: response.data.data.occlusion,
      angle: response.data.data.angle,
      location: response.data.data.location,
      face_probability:response.data.data.face_probability
    };
    
    ElMessage.success('上传成功');
  }
  
}catch(error){
ElMessage.error('请求异常：'+error.message);
}

finally { // 关键修复：始终执行重置
    isUploading.value = false;
  }};

const openCamera = async () => {
  try {
    stream.value = await navigator.mediaDevices.getUserMedia({ video: true });
    video.value.srcObject = stream.value;
    video.value.play();
    isCameraActive.value = true;
    photoData.value = null;
  } catch (error) {
    ElMessage.error('无法访问摄像头: ' + error.message);
  }
};

const takePhoto = () => {
  const canvas = document.createElement('canvas');
  canvas.width = video.value.videoWidth;
  canvas.height = video.value.videoHeight;
  canvas.getContext('2d').drawImage(video.value, 0, 0);
  photoData.value = canvas.toDataURL('image/jpeg');
  stopCamera();
};

const stopCamera = () => {
  if (stream.value) {
    stream.value.getTracks().forEach(track => track.stop());
    stream.value = null;
    video.value.srcObject = null;
  }
  isCameraActive.value = false;
};

const retakePhoto = () => {
  photoData.value = null;
  openCamera();
};
</script>

<style scoped>
.camera-container {
  max-width: 1000px;
  margin: 20px auto;
  padding: 25px;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  background: linear-gradient(145deg, #f9f9f9, #ffffff);
}

.camera-section {
  text-align: center;
  margin-bottom: 30px;
}

.camera-preview, .photo-preview {
  width: 100%;
  max-width: 640px;
  max-height: 480px;
  margin-bottom: 25px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #ebeef5;
}

.button-group {
  display: flex;
  justify-content: center;
  gap: 15px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.result-section {
  margin-top: 30px;
  padding: 20px;
  background-color: #f8fafc;
  border-radius: 8px;
}

.result-image {
  max-width: 150px;
  max-height: 100px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.el-divider {
  margin: 25px 0;
}

.el-divider__text {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #409eff;
}
.page-container {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 20px;
}

.header {
  text-align: center;
  margin-bottom: 30px;
  width: 100%;
  max-width: 1200px;
}

.title {
  font-size: 2.5rem;
  color: #2c3e50;
  margin-bottom: 10px;
  font-weight: 600;
  text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
}

.subtitle {
  font-size: 1.2rem;
  color: #7f8c8d;
  margin-top: 0;
}

.camera-container {
  width: 100%;
  max-width: 1200px;
  margin-bottom: 30px;
  box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.2);
}

.footer {
  margin-top: auto;
  text-align: center;
  color: #7f8c8d;
  font-size: 0.9rem;
  padding: 20px 0;
}

.preview-wrapper {
  position: relative;
  margin-bottom: 25px;
  border-radius: 8px;
  background: #f8fafc;
  padding: 15px;
  box-shadow: inset 0 0 10px rgba(0,0,0,0.05);
}

.preview-label {
  position: absolute;
  top: -10px;
  left: 20px;
  background: #409eff;
  color: white;
  padding: 3px 15px;
  border-radius: 15px;
  font-size: 14px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #909399;
  background: #f0f2f5;
  border-radius: 5px;
}

.placeholder p {
  margin-top: 15px;
  font-size: 16px;
}

.button-group {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 25px;
}

.status-indicator {
  text-align: center;
  color: #909998;
  font-size: 14px;
  margin-top: 15px;
}

.status-indicator.active {
  color: #67c23a;
}

.indicator-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #909399;
  margin-right: 8px;
}

.status-indicator.active .indicator-dot {
  background: #67c23a;
}
</style>